package com.xihuanjun.sdk.util;

import com.xihuanjun.sdk.config.SapSLConfig;
import com.xihuanjun.sdk.exception.InitException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.CharEncoding;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.URL;
import java.util.Map;

/**
 * Copyright (C), 2024-08-24
 * FileName: HttpUtils
 * Author:   溪浣君
 * Date:     2024-08-24 9:22
 * Description: 处理HTTP请求的工具类
 */
@Component
@Slf4j
public class HttpUtils {


    private String DOMAIN="";

    @Autowired
    SapSLConfig sapSLConfig;

    @PostConstruct
    public void init(){
        System.out.println("\n" +
                " __  __ ___  _   _  _   _    _     _   _      _  _   _  _   _ \n" +
                " \\ \\/ /|_ _|| | | || | | |  / \\   | \\ | |    | || | | || \\ | |\n" +
                "  \\  /  | | | |_| || | | | / _ \\  |  \\| | _  | || | | ||君\\| |\n" +
                "  /  \\  | | |  _溪|| |_| |/ ___ \\ | |\\浣|| |_| || |_| || |\\  |\n" +
                " /_/\\_\\|___||_| |_| \\___//_/   \\_\\|_| \\_| \\___/  \\___/ |_| \\_|\n" +
                "                                                              \n");
        if(StringUtils.hasText(sapSLConfig.getServerPath())==false ||
                StringUtils.hasText(sapSLConfig.getPassword())==false||
                StringUtils.hasText(sapSLConfig.getUserName())==false||
                StringUtils.hasText(sapSLConfig.getCompanyDataBaseName())==false
        ){

                throw new InitException("配置加载错误，请在yml文件中配置com.xihuanjun.sdk.sl的四个属性，或实现");
        }
        if(sapSLConfig.getServerPath().startsWith("https")==false){
            throw new InitException("配置加载错误，访问sap接口的地址必须以https开头");
        }
        this.DOMAIN=getDomainName(sapSLConfig.getServerPath());
        log.debug("DOMAIN:"+DOMAIN);
    }

    public String getDomainName(String url) {
        String host = "";
        try {
            URL Url = new URL(url);
            host = Url.getHost();
        } catch (Exception e) {
            throw new InitException("配置加载错误，请确保com.xihuanjun.sdk.sl.server-path设置正确");
        }
        return host;
    }

    /**
     * 去除json格式化，为了看日志方便
     * @param resultString
     * @return
     */
    private String compressJson(String resultString){
        resultString=resultString.replaceAll("(?<=\\{)\\s+(?=\\\")|(?<=\\\")\\s+(?=:)|(?<=:)\\s+(?=\\\")|(?<=,)\\s+(?=\\\")|(?<=:)\\s+|\\n","");
        return resultString;
    }

    public String sendGet(String url, Map<String,String> cookiesData, Map headers){
        log.debug("发送GET请求：{}",url);
        BasicCookieStore cookieStore = getCookieStore(cookiesData);
        HttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();

        final HttpGet request = new HttpGet(url);
        if(headers!=null){
            headers.forEach((k,v)->{
                request.addHeader(k.toString(),v.toString());
            });
        }
        HttpResponse execute = null;
        try {
            execute = client.execute(request);
            HttpEntity entity = execute.getEntity();
            String str = EntityUtils.toString(entity);
            str=compressJson(str);
            log.debug("GET请求结果：{}",str);
            return str;
        } catch (IOException e) {
            log.debug("发送GET请求失败："+e.getMessage());
            throw new RuntimeException(e);
        }
    }



    private BasicCookieStore getCookieStore(Map<String,String> cookieData){
        BasicCookieStore cookieStore = new BasicCookieStore();
        if(cookieData!=null) {
            log.info("cookies:{}",cookieData);
            cookieData.forEach((k, v) -> {
                BasicClientCookie cookie = new BasicClientCookie(k, v);
                cookie.setDomain(this.DOMAIN);
                cookie.setPath("/");
                cookieStore.addCookie(cookie);
            });
        }
        return  cookieStore;
    }

    /**
     * 发送一个post请求
     * @param url 请求地址
     * @param cookiesData 往cookie放的数据
     * @param json json数据体
     * @return
     */
    public String sendPost(String url, Map<String, String> cookiesData, String json) throws IOException {
        int connectTimeout=10000;
        int socketTimeout=10000;
        if(url.contains("Login")==false){
            connectTimeout=sapSLConfig.getConnectTimeout();
            socketTimeout=sapSLConfig.getSocketTimeout();
        }
        log.debug("发送POST请求：{}，参数：{}",url,json);
        BasicCookieStore cookieStore = getCookieStore(cookiesData);
        HttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectTimeout)
                .setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build();
        httpPost.setConfig(requestConfig);
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            httpPost.setHeader("Content-Type", "application/json");
            if(json!=null) {
                // 创建请求内容
                StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
                httpPost.setEntity(entity);
            }
            // 执行http请求
            HttpResponse execute = client.execute(httpPost, HttpClientContext.create());
            if(execute.getEntity()==null){
                resultString="";
            }else{
                resultString = EntityUtils.toString(execute.getEntity(), "utf-8");
                resultString=compressJson(resultString);
            }
            log.debug("POST请求结果:"+resultString);
        }  finally {
            try {
                if (response != null)
                    response.close();
            } catch (IOException e) {

            }
        }
        return resultString;
    }

    /**
     * 发送PATCH请求
     * @param url
     * @param cookiesData
     * @param json
     * @return
     */
    public String sendPatch(String url, Map<String, String> cookiesData, String json){
        log.info("发送Patch请求：{}，参数：{}",url,json);
        BasicCookieStore cookieStore = getCookieStore(cookiesData);
        HttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();
        HttpPatch httpPatch = new HttpPatch(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(sapSLConfig.getConnectTimeout())
                .setConnectTimeout(sapSLConfig.getConnectTimeout()).setSocketTimeout(sapSLConfig.getSocketTimeout()).build();
        httpPatch.setConfig(requestConfig);
        String resultString = "";
        HttpResponse response=null;
        try {
            httpPatch.setHeader("Content-Type", "application/json");
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPatch.setEntity(entity);
            // 执行http请求
            response =
                    client.execute(httpPatch, HttpClientContext.create());
            HttpEntity entity1 = response.getEntity();
            if (entity1 != null) {
                log.debug("PATCH - url:{}, response:{}", url, response);
                return EntityUtils.toString(entity1, CharEncoding.UTF_8);
            }
        } catch (Exception e) {
            log.info("发送Patch请求失败："+e.getMessage());
            throw new RuntimeException(e);
        } finally {

        }
        return "";
    }
}
